<!DOCTYPE html>
<html>

<head>
  <title>cannon.js - trimesh demo</title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="css/style.css" type="text/css" />
  <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>

<body>
  <script src="../../feng3d/out/feng3d.js"></script>
  <script src="../out/cannon.js"></script>
  <script src="../build/cannon.demo.js"></script>
  <script src="../libs/dat.gui.js"></script>
  <script src="../libs/Three.js"></script>
  <script src="../libs/TrackballControls.js"></script>
  <script src="../libs/Detector.js"></script>
  <script src="../libs/Stats.js"></script>
  <script src="../libs/smoothie.js"></script>
  <script>

    var demo = new CANNON.Demo();
    var size = 2;

    demo.addScene("Trimesh", function ()
    {

      var shape = CANNON.Trimesh.createTorus(4, 3.5, 16, 16);

      // Create world
      var world = demo.getWorld();
      world.gravity.set(0, 0, -10);
      world.broadphase = new CANNON.NaiveBroadphase();
      world.solver.iterations = 10;

      world.defaultContactMaterial.contactEquationStiffness = 1e7;
      world.defaultContactMaterial.contactEquationRelaxation = 4;

      // ground plane
      var groundShape = new CANNON.Plane();
      var groundBody = new CANNON.Body({ mass: 0 });
      groundBody.addShape(groundShape);
      world.addBody(groundBody);
      demo.addVisual(groundBody);

      // sphere
      var sphereShape = new CANNON.Sphere(1);
      var sphereBody = new CANNON.Body({
        mass: 1,
        shape: sphereShape,
        position: new CANNON.Vector3(3, 3, 11)
      });
      world.addBody(sphereBody);
      demo.addVisual(sphereBody);

      // Shape on plane
      var shapeBody = new CANNON.Body({ mass: 1 });
      shapeBody.addShape(shape);
      var pos = new CANNON.Vector3(0, 0, size);
      shapeBody.position.set(0, 0, size * 2);
      shapeBody.velocity.set(0, 1, 1);
      shapeBody.angularVelocity.set(0, 0, 0);
      world.addBody(shapeBody);
      demo.addVisual(shapeBody);
    });

    demo.addScene("Raycasting", function ()
    {

      var shape = CANNON.Trimesh.createTorus(4, 3.5, 16, 16);

      // Create world
      var world = demo.getWorld();
      world.gravity.set(0, 0, 0);

      // particle as marker for the raycast hit
      var N = 5;
      var particleShape = new CANNON.Particle();
      var particleBodies = [];
      for (var i = 0; i < N * N; i++)
      {
        var particleBody = new CANNON.Body({
          mass: 1,
          shape: particleShape,
          collisionResponse: false
        });
        world.addBody(particleBody);
        demo.addVisual(particleBody);
        particleBodies.push(particleBody);
      }

      // Shape on plane
      var shapeBody = new CANNON.Body({ mass: 1, position: new CANNON.Vector3(0.01, 0.01, 0.01) });
      shapeBody.addShape(shape);
      shapeBody.angularVelocity.set(0, 1, 0);
      world.addBody(shapeBody);
      demo.addVisual(shapeBody);

      var from = new CANNON.Vector3(10, 1, 0);
      var to = new CANNON.Vector3(-10, 1, 0);
      var result = new CANNON.RaycastResult();
      var raycastOptions = {};
      var listener = function (evt)
      {
        for (var i = 0; i < N; i++)
        {
          for (var j = 0; j < N; j++)
          {
            from.set(
              10,
              i * 0.1,
              j * 0.1
            );
            to.set(
              -10,
              i * 0.1,
              j * 0.1
            );
            result.reset();
            world.raycastClosest(from, to, raycastOptions, result);
            particleBodies[i * N + j].position.copy(result.hitPointWorld);
          }
        }
      };
      world.addEventListener('postStep', listener);
      var destroyer = function ()
      {
        world.removeEventListener('postStep', listener);
        demo.removeEventListener('destroy', destroyer);
      };
      demo.addEventListener('destroy', destroyer);
    });

    demo.start();

  </script>
</body>

</html>